import codecs
from wineArea import Area, dumpDataStr
from appellationArea import GroupAppellationArea, AppellationArea

class RegionArea(Area):
    _interActiveArea = False    

    _debugPrefix = '  R '

    def addSubArea(self, area, addUserArea=True, groupApp=True,**args):        
        if groupApp:
            subAreaClass = GroupAppellationArea
        else:
            subAreaClass = AppellationArea
        subAreas = self._build_subAreas(addUserArea)
        #print ' xxxx Region Area ', self.name, '  adding ',area , ' to user=',addUserArea, subAreas
        if isinstance(area,basestring):
            #print 'region building area',area, args
            area = subAreaClass(area, parentArea=self, **args)            
        subAreas[area.name] = area
        area.parentArea = self
        return area

    def __getitem__(self,s):
        area = self.getSubArea(s, fuzzy = False)
        if area is None: # build it !
            area = self.addSubArea(s, True, groupApp=False)
        return area

    def __setitem__(self,s, a):
        area = self.addUserArea( s, addUserArea= True, groupApp=False)
        return area



    def getSubAreaRec(self, aname, fuzzy=False, includeGroupArea=True):
        """Get a sub-area or a sub-sub area if includeGroupArea=True. """
        realAppellationKeys = {}
        for n,a in self.subAreasItems():
            if isinstance(a, AppellationArea):
                realAppellationKeys[n] = a
            else:
                # must be a group Area
                if includeGroupArea:
                    realAppellationKeys[n]=a
                realAppellationKeys.update( (n,suba) for n,suba in  a.subAreasItems() )
        #print ' RegionArea getSubArea' ,realAppellationKeys.keys()
        if aname in realAppellationKeys:
            return realAppellationKeys[aname]
        elif fuzzy:
            anameL = difflib.get_close_matches(aname, realAppellationKeys.keys(), 1, cutoff=0.7)
            if anameL != []:
                print " FUZZY search found ", anameL[0] ," for ",aname
                return realAppellationKeys[anameL[0]]
        return None

    @staticmethod
    def dumpSystemSubArea(self,i=1):
        if self._system_subAreas is None :
            return '{}'
        l = []
        pre = '    '*i
        for a in self._system_subAreas.values():
            l.append( pre+'u"%s" : %s,\n'%(a.name, a.dumpSystemSubArea(i+1) ) )
        s = '{\n'+ ''.join(l) +'}\n'
        
        return s

    def dumpSystemData(self):
        
        dpath = self.dataPath()
        ds = dumpDataStr.substitute(name=self.name, cepages = str(self._system_cepages))
        ds += self.dumpSystemSubArea(self) +'\n}'
        
        f = codecs.open(dpath+'.py', 'w',encoding='utf-8')
        f.write(ds)
        f.close()

    def readSystemData(self):
        dpath = self.dataPath()+'.py'
        d= self.readSystemDataFromFile(dpath)
        if d == {}:
            return
        dic = d['dic']
        if dic['cepages'] : self._system_cepages = dic['cepages']

        self.localname = dic['localname']
        for aname, adic in dic['areas'].iteritems():
            if isinstance(adic, dict):
                area = GroupAppellationArea(name = aname, parentArea=self)
            else:
                area = self.subAreaClass(name = aname, parentArea=self)
            area.readSystemData(adic)
            self.addSubArea(area,addUserArea=False)
        

    def getCountry(self):
        return self.parentArea 


    def buildAllAppDic(self):
        from utils import OrderedDictWithLocal
        allAppellation = OrderedDictWithLocal()

        from appellationArea import AppellationArea, GroupAppellationArea
        for a in self._system_subAreas.values():
            if isinstance(a, AppellationArea):
                allAppellation[a.name] = a
            elif isinstance(a, GroupAppellationArea):
                allAppellation.update(a._system_subAreas)
        return allAppellation
    
    def _updateUDataFromSData(self):
        if self._user_subAreas is not None and self._system_subAreas is not None :
            print ' updates in ',self.name
            # IMPORTANT a user-made appellation can correspond to a system appelation inside this region
            # or inside a GroupAppellationArea inside this region.
            
            # So, first build an OrderedDictWithLocal to reference all appellations directly in this region or in its
            # sub GroupAppellationArea
            from utils import OrderedDictWithLocal
            allAppellation = OrderedDictWithLocal()

            from appellationArea import AppellationArea, GroupAppellationArea
            for a in self._system_subAreas.values():
                if isinstance(a, AppellationArea):
                    allAppellation[a.name] = a
                elif isinstance(a, GroupAppellationArea):
                    allAppellation.update(a._system_subAreas)
                
            print ' allAppellation ',allAppellation.keys()
            systSubA = self._system_subAreas        
            toUpdate = []
            # loop over user's areas
            for a in self._user_subAreas.values():
                print ' --> testing area ',a.name
                # if it exists in the system areas
                s_a = allAppellation.getApproximate(a.name, checkLocal=True)
                if s_a is not None: # mark it to be updated
                    toUpdate.append( (a, s_a ) )
            print ' ___ num to update =', len(toUpdate)
            for (ua , sa ) in toUpdate:
                if self.confirmUDtransferToSD(ua, sa):
                    ua._transferUDataToSData(sa)
                self._user_subAreas.pop(ua.name)
        # proceed to sub areas
        for a in self.subAreas():
            a._updateUDataFromSData()
        print '______________ ',self.name ,' and subarea done _________'
